From 7c12e6480b03bca9795343f5a38754740e36d86c Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Tue, 22 Oct 2013 18:42:01 +0200 Subject: [PATCH] GtkWidget: Avoid lingering clock frame updates For some widgets, like GtkTreeView, which setup a clock frame update during realize, it was possible to call gdk_frame_clock_begin_updating() twice, but only ever disconnecting from it once. This happens because the realized flag is set at an unpredictable time by the GtkWidget's realize implementation. Keep the signal handler ID from us connecting to the "update" signal to avoid connecting to it twice. This fixes high wake-up count from any application using GtkTreeView, even idle ones. https://bugzilla.gnome.org/show_bug.cgi?id=710666 --- gtk/gtkwidget.c | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index c4068d1acf..7acfd652b4 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -510,6 +510,7 @@ struct _GtkWidgetPrivate /* Animations and other things to update on clock ticks */ GList *tick_callbacks; + guint clock_tick_id; /* A hash by GType key, containing hash tables by widget name */ @@ -4731,12 +4732,11 @@ unref_tick_callback_info (GtkWidget *widget, g_slice_free (GtkTickCallbackInfo, info); } - if (priv->tick_callbacks == NULL && priv->realized) + if (priv->tick_callbacks == NULL && priv->clock_tick_id) { GdkFrameClock *frame_clock = gtk_widget_get_frame_clock (widget); - g_signal_handlers_disconnect_by_func (frame_clock, - (gpointer) gtk_widget_on_frame_clock_update, - widget); + g_signal_handler_disconnect (frame_clock, priv->clock_tick_id); + priv->clock_tick_id = 0; gdk_frame_clock_end_updating (frame_clock); } } @@ -4834,12 +4834,12 @@ gtk_widget_add_tick_callback (GtkWidget *widget, priv = widget->priv; - if (priv->tick_callbacks == NULL && priv->realized) + if (priv->realized && !priv->clock_tick_id) { GdkFrameClock *frame_clock = gtk_widget_get_frame_clock (widget); - g_signal_connect (frame_clock, "update", - G_CALLBACK (gtk_widget_on_frame_clock_update), - widget); + priv->clock_tick_id = g_signal_connect (frame_clock, "update", + G_CALLBACK (gtk_widget_on_frame_clock_update), + widget); gdk_frame_clock_begin_updating (frame_clock); } @@ -4898,11 +4898,11 @@ gtk_widget_connect_frame_clock (GtkWidget *widget, if (GTK_IS_CONTAINER (widget)) _gtk_container_maybe_start_idle_sizer (GTK_CONTAINER (widget)); - if (priv->tick_callbacks != NULL) + if (priv->tick_callbacks != NULL && !priv->clock_tick_id) { - g_signal_connect (frame_clock, "update", - G_CALLBACK (gtk_widget_on_frame_clock_update), - widget); + priv->clock_tick_id = g_signal_connect (frame_clock, "update", + G_CALLBACK (gtk_widget_on_frame_clock_update), + widget); gdk_frame_clock_begin_updating (frame_clock); } @@ -4919,11 +4919,10 @@ gtk_widget_disconnect_frame_clock (GtkWidget *widget, if (GTK_IS_CONTAINER (widget)) _gtk_container_stop_idle_sizer (GTK_CONTAINER (widget)); - if (priv->tick_callbacks) + if (priv->clock_tick_id) { - g_signal_handlers_disconnect_by_func (frame_clock, - (gpointer) gtk_widget_on_frame_clock_update, - widget); + g_signal_handler_disconnect (frame_clock, priv->clock_tick_id); + priv->clock_tick_id = 0; gdk_frame_clock_end_updating (frame_clock); } -- 2.30.2